﻿//#include "devices.h"
//------mainApp.h先决
#include "const.h"//
#include "curve.h"
#include "inisetter.h"
#include "devices.h"

#include "mainApp.h"




devices::devices(void)
{
	//数据初始化
	pMotor=0;
	pReader=0;
	pthread=0;
	this->pflag=0;
	pPara=0;

	typedef bool (*setupMotorEngine)(motorInterface& );
	typedef bool (*setupReaderEngine)(readerInterface& );
	//加载
	pMotor=::LoadLibraryW(L"motor.dll");
	if(!pMotor)
		pMotor=::LoadLibraryW(L"motor_mc200.dll");
	if(!pMotor)
	{
		wxMessageBox(L"步进电机驱动没有找到");
	}
	else
	{
		setupMotorEngine setupMotor= (setupMotorEngine)::GetProcAddress(pMotor, "setupMotorEngine");
		setupMotor(motor);
		//wxMessageBox(L"步进电机端口错误，请确保端口存在以及没有被使用");

	}
	//加载锁相等读取设备驱动
	pReader=::LoadLibraryW(L"lokcinSTF.dll");
	if(!pReader)
		pReader=::LoadLibraryW(L"lockin7265.dll");
	if(!pReader)
		pReader=::LoadLibraryW(L"boxcar.dll");
	if(!pReader)
	{
		wxMessageBox(L"读取仪器的驱动没有找到");
	}
	else
	{
		setupReaderEngine setupReader= (setupReaderEngine)::GetProcAddress(pReader, "setupReaderEngine");
		setupReader(readDivice);
		//	wxMessageBox(L"读取仪器的端口错误，请确保端口存在以及没有被使用");

	}
}


devices::~devices(void)
{
	this->closeMotorPort();
	this->closeReaderPort();
}


void devices::openMotorPort(int com)
{
	if(!motor.openCom(com))
		msg(L"步进电机端口打开失败！");
}
void devices::openReaderPort(int com)
{
	if(!readDivice.openCom(com))//1 index
		msg(L"锁相端口打开失败！");
}

void devices::closeMotorPort()
{
	motor.closeCom();
}
void devices::closeReaderPort()
{
	readDivice.closeCom();
}

void devices::start()
{
	if(pthread)
		::CloseHandle(pthread);//清理上一次的资源
	pthread=CreateThread(0,0,workTh,this,0,0);
}


static DWORD _stdcall workTh(LPVOID p)
{
	devices*dev=(devices*)p;
	MainFrame*cpp= (MainFrame*)dev->app;
	cpp->Log2(L"步进电机运行中...");


	double dbuf=0;

	wxArrayString paraMotor=getArray(0,*dev->pPara),
		paraReader=getArray(1,*dev->pPara),
		paraFunction=getArray(2,*dev->pPara);

	//步进电机
	long steps,intervalSteps,divide,xaxis;
	paraMotor[0].ToLong(&steps);
	paraMotor[1].ToLong(&intervalSteps);
	paraMotor[3].ToLong(&divide);
	//选择电机
	xaxis=(paraMotor[4]==L"X");
	dev->motor.selAxis(xaxis);

	bool forward=(paraMotor[2]==L"正向行走");

	// 读取仪器
	int channel;
	
	if(paraReader[0]==L"1")
		channel=1;
	else if(paraReader[0]==L"2")
		channel=2;
	else
		channel=3;//代表双通道读取

#ifdef _DEBUG
	//wxLogMessage(paraReader[0]);
	wxLogMessage(L"channel：%d",channel);
#endif
	
	//额外功能使用情况
	//扫描次数
	long scanTimes;
	paraFunction[1].ToLong(&scanTimes);
	bool bBack=(paraFunction[0]==_T("返回起始位置"));
	bool bSeakPeak=(paraFunction[0]==_T("返回最高峰(寻峰)"));

	static short delay=100;//等待电机延时

#ifdef _DEBUG
	wxLogMessage(L"正在清理旧点内存,red=%d;blue=%d",dev->red.size(),dev->blue.size());
	//if(dev->red.size()>0)
	//wxLogMessage(L"查看red[0]->x=%f;y=%f",dev->red[0]->x,dev->red[0]->y);
#endif

	for(unsigned int i=0;i!=dev->red.size();i++)
	{
		delete dev->red[i];
	}
	for(unsigned int i=0;i!=dev->blue.size();i++)
	{
		delete dev->blue[i];
	}
	dev->blue.clear();
	dev->red.clear();
	
	if(channel==1)
	{
		dev->red.reserve(steps);
		for(int i=0;i<steps;i++)
		{
			dev->red.push_back(new Point(0,0));
		}
	}
	else if(channel==2)
	{
		dev->blue.reserve(steps);
		for(int i=0;i<steps;i++)
		{
			dev->blue.push_back(new Point(0,0));
		}
	}
	else
	{
		dev->red.reserve(steps);
		dev->blue.reserve(steps);
		for(int i=0;i<steps;i++)
		{
			dev->red.push_back(new Point(0,0));
			dev->blue.push_back(new Point(0,0));
		}
	}
#ifdef _DEBUG
	wxLogMessage(L"清理旧点完成，新点预定数目：red%d blue=%d",dev->red.size(),dev->blue.size());
#endif
	int alreadyPath=0;//记录已走路程

	char buf[100]="";
	wxString wxMsg=L"";
	//开始扫描
			//设置细分
	dev->motor.setDivide(divide);

	bool suceed=false;
	for(int scanIndex=0;scanIndex<scanTimes && *dev->pflag==devices::state_run;scanIndex++)
	{
		cpp->clearChart();


		alreadyPath=0;//每次重复开始已经到达起点

		for (int ii = 0;ii <steps  && *dev->pflag==devices::state_run; ii++)
		{
			dev->motor.fastSteps(intervalSteps,forward);
			
			alreadyPath+=intervalSteps;

			Sleep(delay);

			if (channel==1)
			{
				//memset(buf,0,wcslen(buf));
				suceed=dev->readDivice.pgetx(buf);
				
				dbuf=atof(buf);
				dev->red[ii]->y+=dbuf;
				if(scanIndex==0)
					dev->red[ii]->x=ii+1;

				cpp->addRed(ii+1,dbuf);
			}
			else if (channel==2)
			{
				suceed=dev->readDivice.pgety(buf);

				dbuf=atof(buf);
				dev->blue[ii]->y+=dbuf;
				if(scanIndex==0)
				dev->blue[ii]->x=ii+1;
				cpp->addBlue(ii+1,dbuf);
			}
			else if (channel==3)
			{
				suceed=dev->readDivice.pgetall(buf);

				wxString temp(buf,wxConvUTF8);
				wxArrayString arr=wxStringTokenize(temp,L"\r");

				dbuf=_wtof(arr[0]);
				dev->red[ii]->y+=dbuf;
				if(scanIndex==0)
				dev->red[ii]->x=ii+1;
				cpp->addRed(ii+1,dbuf);

				dbuf=_wtof(arr[1]);
				dev->blue[ii]->y+=dbuf;
				if(scanIndex==0)
				dev->blue[ii]->x=ii+1;
				cpp->addBlue(ii+1,dbuf);
			}

			if(!suceed)
			{
				cpp->Log2(L"读取仪器失败,已经停止");
				::ExitThread(0);
			}

			float percent=100.f*(scanIndex*steps+ii+1.f)/(scanTimes*steps);

			wxMsg.Printf(L"进度:%0.2f%%",percent);

			//这里处理暂停
			cpp->Log3(wxMsg);
			while(*dev->pflag==devices::state_pause)
			{
				Sleep(800);
			}

		}
		//这里处理停止
		if(*dev->pflag==devices::state_stop)
		{
			// 如果需要倒退
			if(bBack)
			{
				cpp->Log2(L"电机正在返回...");
				dev->motor.fastSteps(alreadyPath,!forward);
				
			}
			cpp->Log2(L"步进电机运行结束");
			::ExitThread(0);
		}

		if(scanIndex!=scanTimes -1)
		{
			int iii=steps*intervalSteps;
			dev->motor.fastSteps(iii,!forward);
			//额外等待
			Sleep(delay);
		}
		cpp->Log2(L"步进电机正在进行下一次扫描...");
	}
	//这里设置标记为完成
	*dev->pflag=devices::state_stop;

	
	if(scanTimes!=1)
	{
		cpp->Log2(L"平均处理并显示...");
		//平均处理	
		for(int index_=0;index_<steps;index_++)
		{
			if (channel==1)
				dev->red[index_]->y=dev->red[index_]->y/scanTimes;
			else if (channel==2)
				dev->blue[index_]->y=dev->blue[index_]->y/scanTimes;
			else
			{
				dev->red[index_]->y=dev->red[index_]->y/scanTimes;
				dev->blue[index_]->y=dev->blue[index_]->y/scanTimes;
			}
		}
		//将数据显示

		cpp->clearChart();
#ifdef _DEBUG
		wxLogMessage(L"正在重新绘图");
#endif

		cpp->addData(dev->red,dev->blue);

		//返回
	}

	if(bBack)
	{	
		int iii=steps*intervalSteps;
		dev->motor.fastSteps(iii,!forward);
	}
	else if(bSeakPeak)
	{
		cpp->Log2(L"电机寻峰中...");
		double Y_max = dev->red[0]->y; int X_max = steps-1;
		for (int k1 = 1; k1 < steps; k1++)
		{
			if (Y_max <= dev->red[k1]->y)//最后一个高峰
			{
				Y_max = dev->red[k1]->y;
				X_max = steps-1-k1;
			}
		}
		if (X_max == 0)
		{
			return 0;
		}

		dev->motor.fastSteps(X_max,!forward);
		
	}

	cpp->Log2(L"步进电机运行结束");
	return 0;

}
